home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 7 / Gekikoh Dennoh Club Vol. 7 (Japan).7z / Gekikoh Dennoh Club Vol. 7 (Japan) (Track 01).bin / games / otoko / source.lzh / FuncEnemy / lboss04c.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-14  |  9.2 KB  |  372 lines

  1. /* 4面ボスコア */
  2. #include <xsp2lib.h>
  3.  
  4. #include "../otoko.h"
  5. #include "../player.h"
  6. #include "../enemy.h"
  7. #include "../eshot.h"
  8. #include "../effect.h"
  9. #include "../priority.h"
  10. #include "../entry.h"
  11. #include "../sound.h"
  12. #include "../psearch.h"
  13.  
  14. #define HP_0    3000        /* 耐久力 */
  15. #define HP_1    1000        /* 耐久力がこれ以下になったら第2段階に */
  16.  
  17. #define    TIMER_1    4000        /* これ以上時間が経ったら第2形態に */
  18. #define    TIMER_2    6000        /* これ以上時間が経ったら自爆 */
  19.  
  20. #define SPEED_1        10    /* 加速度 */
  21. #define SPEED_1N    5    /* 加速度を足す回数 */
  22.  
  23. #define SPEED_2        30    /* 加速度 */
  24. #define SPEED_2N    15    /* 加速度を足す回数 */
  25.  
  26. #define SEQ_DEATH    5
  27.  
  28.  
  29.  
  30. enum {
  31.     MOVETO_INIT = 0,    /* 初期状態 */
  32.     MOVETO_C2L,        /* 中央から左に移動 */
  33.     MOVETO_L2C,
  34.     MOVETO_C2R,
  35.     MOVETO_R2C,
  36. };
  37.  
  38. static short EnemyMoveLBoss04C (ENEMY *);
  39. static void EnemyTiniLBoss04C (ENEMY *);
  40.  
  41.  
  42. void EnemyInitLBoss04C (ENEMY * p)
  43. {
  44.     p->vx = 0;
  45.     p->vy = -8 << 16;
  46.  
  47.     /* 当り判定 */
  48.     p->hit_px = p->hit_py = p->hit_sx = p->hit_sy = p->hit_cx = 0;
  49.     p->timer = 0;
  50.     p->damage = 0;
  51.     p->flash = 0;
  52.     p->hp = HP_0;
  53.     p->pt = obj_lboss04 + 9;
  54.     p->seq = 0;
  55.     if (standard_play)    /* 標準設定か? */
  56.         p->core_info = PALET_CORE_RED | PRIORITY_BOSS_CORE;
  57.     else
  58.         p->core_info = PALET_CORE_BLUE | PRIORITY_BOSS_CORE;
  59.  
  60.     p->func_enemy_move = EnemyMoveLBoss04C;
  61.     p->func_enemy_tini = EnemyTiniLBoss04C;
  62.  
  63.     entry_counter_stop = !0;/* エントリーカウンター停止 */
  64. }
  65.  
  66.  
  67.  
  68. static short EnemyMoveLBoss04C (ENEMY * p)
  69. {
  70.     /* 速度を足して上位ワード(固定整数部)だけ取り出す */
  71.     p->x = (p->lx += p->vx) >> 16;
  72.     p->y = (p->ly += p->vy) >> 16;
  73.     p->timer++;
  74.  
  75.     switch (p->seq) {
  76.         /* 上に上がってくる */
  77.     case 0:
  78.         /* 本体を表示 */
  79.         xobj_set (p->x, p->y + 8, obj_lboss04 + 7, PALET_LBOSS04 | PRIORITY_BOSS);
  80.         if (p->y < 192)
  81.             p->seq++;
  82.         break;
  83.  
  84.         /* 減速 */
  85.     case 1:
  86.         /* 本体を表示 */
  87.         xobj_set (p->x, p->y + 8, obj_lboss04 + 7, PALET_LBOSS04 | PRIORITY_BOSS);
  88.         if (p->vy < -16384) {
  89.             p->vy += 16384;
  90.         } else {
  91.             p->seq++;
  92.             p->vy = 0;
  93.             EffectInit (EFFECT_EXPL, 0, p->x, p->y);
  94.             EffectInit (EFFECT_EXPL, 0, p->x + 32, p->y + 24);
  95.             EffectInit (EFFECT_EXPL, 0, p->x - 32, p->y + 32);
  96.             SoundSetSE (SE_EXPL_M);    /* 中ボス爆発音 */
  97.             if (disp_level == DISP_LEVEL_HIGH)
  98.                 EffectInit (EFFECT_HAHENMINI, 0, p->x, p->y);
  99.             p->m_work = 0;
  100.             p->hit_px = 24;
  101.             p->hit_py = 16;
  102.             p->hit_sx = 24;
  103.             p->hit_sy = 16;
  104.             p->hit_cx = 24;
  105.         }
  106.         break;
  107.  
  108.         /* しばらく待つ */
  109.     case 2:
  110.         if (p->m_work++ > 15) {
  111.             p->seq++;
  112.             p->m_work = MOVETO_INIT;    /* 移動方向 */
  113.             p->m_work3 = 0;
  114.             p->s_work = p->s_work2 = p->s_work3 = 0;
  115.             p->s_angle = 0;
  116.         }
  117.         break;
  118.  
  119.         /* 攻撃開始 */
  120.     case 3:
  121.         /* まず移動処理 */
  122.         if (p->m_work == MOVETO_INIT) {
  123.             /* 初期状態なら */
  124.             if (p->x > player->x)
  125.                 p->m_work = MOVETO_C2L;    /* 移動方向 */
  126.             else
  127.                 p->m_work = MOVETO_C2R;    /* 移動方向 */
  128.             p->m_work2 = 0;
  129.         }
  130.         if (p->m_work2 == 0) {
  131.             /* 初回なら */
  132.             signed short dx, dy;
  133.             signed short dx_table[5] =
  134.             {0, 96 + 16, 128 + 16, 256 - 96 + 16, 128 + 16};
  135.             short m_work_table[5] =
  136.             {MOVETO_INIT, MOVETO_L2C, MOVETO_C2R, MOVETO_R2C, MOVETO_C2L};
  137.  
  138.             p->m_work2 = !0;
  139.             /* 順に左→中央→右→中央→左へ移動 */
  140.             dx = dx_table[p->m_work];
  141.             p->m_work = m_work_table[p->m_work];
  142.  
  143.             /* player->x は乱数の種として使用しています */
  144.             dy = (((unsigned short) rndtable[(player->x) & 0xff]) / 8 - 16 + 80 + 16);
  145.             /* 移動方向を設定 */
  146.             SubEnemyMoveToInit (p, dx, dy, SPEED_1, SPEED_1N);
  147.         } else {
  148.             /* 設定値に従って移動 */
  149.             if (SubEnemyMoveTo (p) < 0)
  150.                 p->m_work2 = 0;    /* 移動方向再設定 */
  151.         }
  152.         if ((p->hp < HP_1) || (p->timer > TIMER_1)) {
  153.             p->seq++;
  154.             p->s_work = p->s_work2 = p->s_work3 = 0;
  155.             EffectInit (EFFECT_EXPL, 0, p->x, p->y);
  156.             SoundSetSE (SE_EXPL_M);    /* 中ボス爆発音 */
  157.             if (!eshot_erase)
  158.                 eshot_erase = ESHOT_ERASE;    /* 弾消し */
  159.         }
  160.         /* 次に攻撃処理 */
  161.         switch (p->s_work) {
  162.             /* うずまき弾 */
  163.         case 0:
  164. #define INTERVAL0    2
  165. #define SPEED_SHOT0        22
  166. #define SPEED_SHOT0_1    16    /* 炸裂弾の速度 */
  167.             if (p->s_work2++ > INTERVAL0) {
  168.                 p->s_work2 = 0;
  169.                 EshotInit (ESHOT_NRG03, p->x, p->y, SPEED_SHOT0, p->s_angle, 4);
  170.                 EshotInit (ESHOT_NRG03, p->x, p->y, SPEED_SHOT0, p->s_angle + 64 * 1, 4);
  171.                 EshotInit (ESHOT_NRG03, p->x, p->y, SPEED_SHOT0, p->s_angle + 64 * 2, 4);
  172.                 EshotInit (ESHOT_NRG03, p->x, p->y, SPEED_SHOT0, p->s_angle + 64 * 3, 4);
  173.                 SoundSetSE (SE_ESHOT);    /* 敵ショット音 */
  174.                 p->s_angle += 8;
  175.                 p->s_work3++;
  176.                 if (p->s_work3 >= 120) {
  177.                     p->s_work++;
  178.                     p->s_work3 = 0;
  179.                 }
  180.             }
  181.             break;
  182.  
  183.             /* 十字にゆっくり回転 */
  184.         case 1:
  185.             if (p->s_work2++ > INTERVAL0) {
  186.                 p->s_work2 = 0;
  187.                 EshotInit (ESHOT_NRG03, p->x, p->y, SPEED_SHOT0, p->s_angle, 4);
  188.                 EshotInit (ESHOT_NRG03, p->x, p->y, SPEED_SHOT0, p->s_angle + 64 * 1, 4);
  189.                 EshotInit (ESHOT_NRG03, p->x, p->y, SPEED_SHOT0, p->s_angle + 64 * 2, 4);
  190.                 EshotInit (ESHOT_NRG03, p->x, p->y, SPEED_SHOT0, p->s_angle + 64 * 3, 4);
  191.                 SoundSetSE (SE_ESHOT);    /* 敵ショット音 */
  192.                 p->s_angle += 2;
  193.                 p->s_work3++;
  194.                 if (p->s_work3 >= 120) {
  195.                     p->s_work--;
  196.                     p->s_work3 = 0;
  197.                 }
  198.             }
  199.             break;
  200.         }
  201.         break;
  202.  
  203.         /* 本当の最終段階 */
  204.     case 4:
  205.         if (p->m_work2 == 0) {
  206.             /* 初回なら */
  207.             signed short dx, dy;
  208.             signed short dx_table[5] =
  209.             {0, 54 + 16, 128 + 16, 256 - 54 + 16, 128 + 16};
  210.             short m_work_table[5] =
  211.             {MOVETO_INIT, MOVETO_L2C, MOVETO_C2R, MOVETO_R2C, MOVETO_C2L};
  212.  
  213.             p->m_work2 = !0;
  214.             /* 順に左→中央→右→中央→左へ移動 */
  215.             dx = dx_table[p->m_work];
  216.             p->m_work = m_work_table[p->m_work];
  217.  
  218.             /* player->x は乱数の種として使用しています */
  219.             if (SHORT_LY < 80)
  220.                 dy = (((unsigned short) rndtable[(player->x) & 0xff]) / 4 + 32 + 16);
  221.             else
  222.                 dy = 64;
  223.             /* 移動方向を設定 */
  224.             SubEnemyMoveToInit (p, dx, dy, SPEED_2, SPEED_2N);
  225.         } else {
  226.             /* 設定値に従って移動 */
  227.             if (SubEnemyMoveTo (p) < 0)
  228.                 p->m_work2 = 0;    /* 移動方向再設定 */
  229.         }
  230.  
  231.         if (p->timer > TIMER_2) {    /* 時間切れ */
  232.             p->seq = SEQ_DEATH;
  233.             p->m_work = 0;
  234.             p->work = 0;    /* 時間切れの時 */
  235.         }
  236.         /* 次に攻撃処理 */
  237.         switch (p->s_work) {
  238.             /* 炸裂弾 */
  239.         case 0:
  240. #define INTERVAL3_0    12
  241. #define SPEED_SHOT3_0    8    /* 炸裂弾の速度 */
  242. #define SPEED_SHOT3_1    16
  243.             if (p->s_work2++ > INTERVAL3_0) {
  244.                 short h;
  245.                 char a = 9;
  246.                 p->s_work2 = 0;
  247.                 for (h = 0; h < 8; h++) {
  248.                     EshotInit (ESHOT_NRG02, p->x, p->y, SPEED_SHOT3_0, a += 16, 4);
  249.                     EshotInit (ESHOT_NRG05, p->x, p->y, SPEED_SHOT3_1, a += 16, 4);
  250.                 }
  251.                 SoundSetSE (SE_EBOMB_M);
  252.                 if (p->s_work3++ > 3) {
  253.                     p->s_work++;
  254.                     p->s_work3 = 0;
  255.                 }
  256.             }
  257.             break;
  258.  
  259.         case 1:
  260. #define INTERVAL3_1    12
  261. #define SPEED_SHOT3_11    8    /* 炸裂弾の速度 */
  262. #define SPEED_SHOT3_12    12
  263. #define SPEED_SHOT3_13    16
  264.             if (p->s_work2++ > INTERVAL0) {
  265.                 short h;
  266.                 p->s_work2 = 0;
  267.                 for (h = 0; h < 4; h++) {
  268.                     EshotInit (ESHOT_NRG02, p->x, p->y, SPEED_SHOT3_11, rndtable[p->angle++] & 0xfe, 4);
  269.                     EshotInit (ESHOT_NRG03, p->x, p->y, SPEED_SHOT3_12, rndtable[p->angle++] & 0xfe, 4);
  270.                     EshotInit (ESHOT_NRG24N, p->x, p->y, SPEED_SHOT3_13, rndtable[p->angle++] & 0xfe, 4);
  271.                 }
  272.                 SoundSetSE (SE_EBOMB_L);
  273.                 if (p->s_work3++ > 3) {
  274.                     p->s_work--;
  275.                     p->s_work3 = 0;
  276.                 }
  277.             }
  278.             break;
  279.         }
  280.         break;
  281.  
  282.  
  283.     case SEQ_DEATH:
  284.         switch (p->m_work) {
  285.         case 0:
  286.             if (SubEnemyMoveToAbort (p) < 0) {    /* 止まるまで待つ */
  287.                 p->m_work++;
  288.                 p->m_work2 = 0;
  289.                 p->m_work3 = 0;
  290.                 /* 当たり判定を無くす */
  291.                 p->hit_px = p->hit_py = p->hit_sx = p->hit_sy = p->hit_cx = 0;
  292.                 if (!eshot_erase)
  293.                     eshot_erase = ESHOT_ERASE;    /* 弾消し */
  294.             }
  295.             break;
  296.         case 1:
  297.             if (p->m_work2++ > 3) {
  298.                 p->m_work2 = 0;
  299.                 p->m_work3++;
  300.                 if (p->m_work3 < 35) {
  301.                     signed short x, y;
  302.                     x = rndtable[(p->timer) & 0xff ^ 0x55] / 4 - 32;
  303.                     y = rndtable[(p->timer) & 0xff ^ 0xaa] / 4 - 32;
  304.                     /* p->timer は乱数の種として使用しています */
  305.                     EffectInit (EFFECT_EXPL, 0, p->x + x, p->y + y);
  306.                     SoundSetSE (SE_EXPL_M);    /* 中ボス爆発音 */
  307.                 }
  308.                 if (p->m_work3 > 40) {
  309.                     short h;
  310.                     for (h = 0; h < 6; h++) {
  311.                         signed short x, y;
  312.                         /* p->timer は乱数の種として使用しています */
  313.                         x = rndtable[(p->timer + h) & 0xff ^ 0x55] - 128;
  314.                         y = rndtable[(p->timer - h) & 0xff ^ 0xaa] - 128;
  315.                         EffectInit (EFFECT_EXPL, 0, p->x + x / 4, p->y + y / 4);
  316.                     }
  317.                     SoundSetSE (SE_EXPL_L);    /* ボスキャラ爆発音 */
  318.                     if (p->work) {    /* ちゃんと倒したか? */
  319.                         if (p->core_info == (PALET_CORE_RED | PRIORITY_BOSS_CORE))
  320.                             EffectInit (EFFECT_POINTS_RED, POINTS_10000, p->x, p->y);
  321.                         else
  322.                             EffectInit (EFFECT_POINTS_BLUE, POINTS_100, p->x, p->y);
  323.                     }
  324.                     player->seq = PLAYER_SEQ_LAST;    /* player.c 参照 */
  325.                     player->seq2 = 0;
  326.                     return (-1);    /* 消去 */
  327.                 }
  328.             }
  329.             break;
  330.         }
  331.         break;
  332.  
  333.     default:
  334.         break;
  335.     }
  336.  
  337.  
  338.     /* 自機ショットに当たった時の処理 */
  339.     if (p->damage) {
  340.         SoundSetSE (SE_CORE_DAMAGE);
  341.         p->info = PALET_RED | PRIORITY_BOSS;
  342.         p->damage_core = 0;
  343.         if ((p->hp -= p->damage) <= 0) {
  344.             /* 死んだ */
  345.             p->seq = SEQ_DEATH;
  346.             p->m_work = 0;
  347.             p->work = !0;    /* ちゃんと倒した時 */
  348.         }
  349.         p->damage = 0;
  350.         p->flash = TIMER_FLASH_DAMAGE;
  351.     } else {
  352.         if ((p->flash++ > TIMER_FLASH_RED) && (p->hp < 700)) {
  353.             p->info = PALET_RED | PRIORITY_BOSS;
  354.             if (p->flash > TIMER_FLASH_NORMAL)
  355.                 p->flash = 0;
  356.         } else {
  357.             p->info = p->core_info;
  358.         }
  359.     }
  360.     xobj_set_st (p);
  361.  
  362.  
  363.     return (0);
  364. }
  365.  
  366.  
  367.  
  368. static void EnemyTiniLBoss04C (ENEMY * p)
  369. {
  370.     entry_counter_stop = 0;    /* エントリーカウンター停止解除 */
  371. }
  372.